<?php
	require_once("./db/database.php");
	
	class Fight_common_AI {
		
		// Deploy to the toponym that with most self's army
		public function deployment($session_key, $continents) {
			$occupied_continents_array = array();
		
			do{ 
				$toponym_array = array();
				$occupied_toponym_arrray = array();
				$possible_continents_array = array();
				
				//Count the player's army on each continent
				$max = -1;
				foreach($continents as $key => $dummy) {
					if (in_array($key, $occupied_continents_array)) {	// Skip fully occupied 
						continue;
					}
					$result = db_query("SELECT COUNT(*) AS total FROM map_status WHERE owner == $session_key AND continent = '$key';");
					$row = db_fetch_array($result);
					if ($row["total"] > $max) {
						$max = $row["total"];
						$max_army_continent = $key ;
					}
				}
				
				// Handle no toponym
				if ($max == 0) {
					return $this->get_random_non_occupied_toponym($continents);
				}
				
				// Find all continents with that number of army
				$result = db_query("SELECT continent, COUNT(*) AS count FROM map_status WHERE owner = $session_key GROUP BY continent");
				//echo "SELECT continent, COUNT(*) AS count FROM map_status WHERE owner = $session_key GROUP BY continent";
				while($row = db_fetch_array($result)) {
					if ($row["count"] == $max) {	// Filter, only need the continent with current max occupied toponym
						//echo $row["continent"] .': '. $row["count"];
						//echo "<br/>";
						$idx = count($possible_continents_array) ;
						$possible_continents_array[$idx] = $row["continent"];
					}
				}
				//echo "possible: ";
				//print_r($possible_continents_array);
				//echo "<br/>";
				
				$rand_num = mt_rand(0, count($possible_continents_array) - 1);
				$selected_continent = $possible_continents_array[$rand_num];
				
				
				// Find all occupied toponym in that continent
				$result = db_query("SELECT toponym FROM map_status WHERE continent = '$selected_continent';");
				$i = 0;
				while($row = db_fetch_array($result)) {
					$occupied_toponym_arrray[$i] = $row["toponym"];
					$i++;
				}
				
				// Put tonponym in that continent to array
				$i = 0;
				foreach($continents[$selected_continent] as $toponym) {
					if (!in_array($toponym, $occupied_toponym_arrray)) {
						$toponym_array[$i] = $toponym;
						$i++;
					}
				}
				
				// Fully occupied continent
				if (count($toponym_array) == 0) {
					$tmp = count($occupied_continents_array);
					$occupied_continents_array[$tmp] = $selected_continent;
					//print_r($occupied_continents_array);
					//echo "<br />";
				}
				
			} while(count($toponym_array) == 0);
			
			//echo $selected_continent . ": ";
			//print_r($occupied_continents_array[$tmp]);
			
			$rand_num = mt_rand(0, count($toponym_array) - 1);
			return $toponym_array[$rand_num];
		}
		
		// Just Random
		public function post_deployment($session_key, $continents) {
			$continent_array = array();
			$i = 0;	
			foreach($continents as $key => $continent) {
				foreach($continent as $toponym) {
					$continent_array[$i] = $toponym;
					$i++;
				}
			}
			do {
				$rand_num = mt_rand(0, $i-1);
				$is_available = $this->check_is_toponym_available($session_key ,$continent_array[$rand_num], true);
			} while (!is_available);
			return $continent_array[$rand_num];
		}
		
		// Just Random
		public function engagement_planning($session_key, $continents, $no_of_refill) {
			$chosen_land_array = array();
			for ($i = 0; $i < $no_of_refill; $i++) {
				$tmp = $this->post_deployment($session_key, $continents);
				if (!in_array($tmp, $chosen_land_array)) {
					$chosen_land_array[$i] = $tmp;
				}
			}
			
			return $chosen_land_array;
		}

		// Fight the common opponent
		public function engagement_attack($session_key) {
			$toponym_count_array = array();
		
			// Count # toponym of each continent
			$result = db_query("SELECT continent, COUNT(*) AS count FROM map_status WHERE owner = $session_key GROUP BY continent");
			while ($row = db_fetch_array($result)) {
				$continent = $row["continent"];
				$count = $row["count"];
				$toponym_count_array[$continent] = $count;
			}
			// Sort the array according to its toponym count
			function cmp($a, $b) {	// in line function
				if ($a == $b) {
					return 0;
				}
				return ($a < $b) ? 1 : -1;
			}
			uasort($toponym_count_array, 'cmp');
			
			foreach ($toponym_count_array as $continent => $toponym_count) {
				if ($toponym_count == 1) {	//Player has only 1 toponym in that continent
					return $this->find_random_opponent_neighbour($session_key);
				}
				
				// Create neighbour array of each toponym in that continent
				$neighbour_array = array();
				$result = db_query("SELECT toponym FROM map_status WHERE troops > 1 AND owner = '$session_key' AND continent = '$continent'");
				while($row = db_fetch_array($result)) {
					$current_toponym = $row["toponym"];
					$neighbour_array[$current_toponym] = $this->get_neighbour_toponyms($current_toponym);
				}
				
				// Find common neighbours
				$interected_neighbour_array = array();
				$possible_source_array = array();
				$i = 0;
				foreach ($neighbour_array as $out_src => $out_nei) {
					foreach ($neighbour_array as $in_src => $in_nei) {
						if ($in_src == $out_src) {	// Won't interact with self
							continue;
						}
						
						$one_intersect_array = array_intersect($out_nei, $in_nei);
						foreach($one_intersect_array as $element) {
							$result = db_query("SELECT owner FROM map_status WHERE toponym = '$element'");
							$row = db_fetch_array($result);
							if ($row["owner"] == $session_key) {
								$is_owner = true;
							} else {
								$is_owner = false;
							}
							
							if (!in_array($element, $interected_neighbour_array) && !$is_owner) {
								
							
								$interected_neighbour_array[] = $element;
								if (!in_array($in_src, $possible_source_array)) {
									$possible_source_array[$element][] = $in_src;
								}
								if (!in_array($out_src, $possible_source_array)) {
									$possible_source_array[$element][] = $out_src;
								}	
							}
						}
					}
				}
				
				// No interection between toponyms
				if (count($interected_neighbour_array) == 0)  {
					continue;
				}
				
				$rand_num = mt_rand(0, count($interected_neighbour_array) - 1);
				$selected_neighbour = $interected_neighbour_array[$rand_num];
				
				$rand_num = mt_rand(0, count($possible_source_array[$selected_neighbour]) - 1);
				$selected_source = $possible_source_array[$selected_neighbour][$rand_num];
				
				return $selected_source . "," . $selected_neighbour;
				//print_r($interected_neighbour_array);
				//echo "<br/>";
				//echo $selected_neighbour;
				//echo "<br/>";
				//print_r($possible_source_array[$selected_neighbour]);
				//echo "<br/>";
				//echo $selected_source;

				/*	
					foreach ($neighbour_array as $src => $nei) {
						echo $src . "====== ";
						print_r($nei);
						echo "<br />";
					} 
				*/	

			}
			
			// No common toponym in all continenets
			return $this->find_random_opponent_neighbour($session_key);
		}
		
		private function find_random_opponent_neighbour($session_key) {
			$possible_source_array = array();
			$possible_target_array = array();
			
			$result = db_query("SELECT toponym FROM map_status WHERE owner = $session_key AND troops > 1");
			$i = 0;
			while($row = db_fetch_array($result)) {
				$possible_source_array[$i] = $row["toponym"];
				$i++;
			}
			$rand_num = mt_rand(0, $i - 1);
			$source = $possible_source_array[$rand_num];
		
			$neighbour_array = $this->get_neighbour_toponyms($source);
			// Check can fight
			foreach ($neighbour_array as $element) {
				$result = db_query("SELECT toponym FROM map_status WHERE toponym = '$element' AND troops > 0 AND owner != $session_key");
				$row = db_fetch_array($result);
				if ($row["toponym"] != "") {
					$idx = count($possible_target_array);
					$possible_target_array[$idx] = $row["toponym"];
				}
			}
			
			if (count($possible_target_array) == 0) {
				return "No";
			}
			
			$rand_num = mt_rand(0, count($possible_target_array) - 1);
			$target = $possible_target_array[$rand_num];
			return $source . "," . $target;
		}

		
		private function check_is_toponym_available($session_key, $toponym, $allow_self_is_owner) {
			$result = db_query("SELECT owner FROM map_status WHERE toponym = '$toponym'");
			$row = db_fetch_array($result);
			if ($row["owner"] == "") {
				return true;
			}
			if ($row["owner"] == $session_key && $allow_self_is_owner) {
				return true;
			} 
			return false;
		}
		
		private function get_neighbour_toponyms($source, $link_info_file = "./map/default_small/link_info.txt") {
			$source = str_replace("_", " ", $source);
			$result_array = array();
			$fh = fopen($link_info_file, 'r');

			while (!feof($fh)) {
				$line = fgets($fh);
				if (strpos($line, stristr(trim($line), trim($source))) === 0) {
					$token = strtok($line, ",>");
					$count = 0;
					while ($token !== false) {
						if ($count > 0) {	// Skip the first one(source)
							$result_array[$count - 1] = str_replace(" ", "_", trim($token));
						}
						$token = strtok(",>");
						$count++;
					}
					break;
				}
			}
			fclose($fh);
			return $result_array;
		}
		
		private function get_random_non_occupied_toponym($continents) {
			$continent_array = array();
			$i = 0;	
			foreach($continents as $key => $continent) {
				foreach($continent as $toponym) {
					$continent_array[$i] = $toponym;
					$i++;
				}
			}
			do {
				$rand_num = mt_rand(0, $i-1);
				$result = db_query("SELECT owner FROM map_status WHERE toponym = '".$continent_array[$rand_num]."'");
				$row = db_fetch_array($result);
			} while ($row["owner"] != "");
			return $continent_array[$rand_num];
		}
		
		// return array(null, 9999) if no possible target
		private function find_weakest_neighbour($session_key, $source) {
			$nei_array = $this->get_neighbour_toponyms($source);
			$neighbour_army_no_array = array();
			
			// Count and find min # army of each neighbour
			$min = 9999;
			foreach($nei_array as $n) {
				$result = db_query("SELECT troops FROM map_status WHERE toponym = '$n' AND owner != $session_key");
				$row = db_fetch_array($result);
				$num = $row["troops"] == "" ? 0 : $row["troops"];
				$neighbour_army_no_array[$n] = $num;
				if ($num < $min && $num > 0) {
					$min = $num;
					$min_neighbour = $n;
				}
			}
			
			//print_r($neighbour_army_no_array);
			//echo $min_neighbour;
			return array($min_neighbour, $min);
		}
		
	}
	

	
?>